﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Web.UI.WebControls;
using System.Xml.Linq;

namespace OfficeLaunch.SharePoint.TwitterMap.TwitterMapWebPart
{
    public class SilverlightPluginGenerator
    {
        /// <summary>Gets or sets user-defined initialization parameters.</summary>
        public List<InitParam> InitParams = new List<InitParam>();

        public SilverlightPluginGenerator()
        {
        }

        public SilverlightPluginGenerator(Uri SourceUri)
        {
            Source = SourceUri;
        }

        public SilverlightPluginGenerator(Uri SourceUri, Unit PluginWidth, Unit PluginHeight)
        {
            Source = SourceUri;
            Width = PluginWidth;
            Height = PluginHeight;
        }

        /// <summary>Specifies the initial width of the Silverlight plug-in area in the HTML page. Can be as a pixel value or as a percentage (a value that ends with the % character specifies a percentage value). For example, "400" specifies 400 pixels, and "50%" specifies 50% (half) of the available width of the browser content area.</summary>
        public Unit Width { get; set; }

        /// <summary>Specifies the initial height of the Silverlight plug-in area in the HTML page. Can be set either as a pixel value or a percentage (a value that ends with the % character specifies a percentage value). For example, "300" specifies 300 pixels, and "50%" specifies 50% (half) of the available height of the browser content area. </summary>
        public Unit Height { get; set; }

        /// <summary>Gets or sets the Uniform Resource Identifier (URI) of the XAP package</summary>
        public Uri Source { get; set; }

        /// <summary>Specifies the ID of the object element</summary>
        public string ID { get; set; }

        /// <summary>Gets or sets a value that indicates whether the hosted content in the Silverlight plug-in can use the HtmlPage.PopupWindow method to display a new browser window.</summary>
        public bool? AllowHtmlPopupWindow { get; set; }

        /// <summary>Sets a value that indicates whether a Silverlight plug-in version earlier than the specified minRuntimeVersion will attempt to update automatically.</summary>
        public bool? AutoUpgrade { get; set; }

        /// <summary>Gets or sets a value that indicates whether the hosted content in the Silverlight plug-in and in the associated run-time code has access to the browser Document Object Model (DOM).</summary>
        public bool? Enablehtmlaccess { get; set; }

        /// <summary>Gets or sets a value that indicates whether the hosted content in the Silverlight plug-in can use a HyperlinkButton to navigate to external URIs.</summary>
        public bool? EnableNavigation { get; set; }

        /// <summary>Gets or sets the background color of the rectangular region that displays XAML content.</summary>
        public Color BackGround { get; set; }

        /// <summary>Specifies the name of the handler to call when the Silverlight plug-in generates a XAML parse error or run-time error at the native-code level.</summary>
        public string OnError { get; set; }

        /// <summary>Specifies the handler for a FullScreenChanged event that occurs whenever the FullScreen property of the Silverlight plug-in changes.</summary>
        public string OnFullScreenChanged { get; set; }

        /// <summary>Establishes the handler for a Loaded event that occurs when the Silverlight plug-in has finished loading into the browser DOM.</summary>
        public string OnLoad { get; set; }

        /// <summary>Specifies a handler for the Resized event that occurs when the Silverlight plug-in's object tag is resized and the  ActualHeight or the ActualWidth of the Silverlight plug-in change.</summary>
        public string OnResize { get; set; }

        /// <summary>Gets or sets the name of the event handler that is called when the source download has finished.</summary>
        public string OnSourceDownloadComplete { get; set; }

        /// <summary>Gets or sets the name of the event handler that is called when the source download progress changes.</summary>
        public string OnSourceDownloadProgressChanged { get; set; }

        /// <summary>Gets or sets the Silverlight version of the control.  Sets the minimum version and install links</summary>
        public SilverlightVersion Version { get; set; }

        public override string ToString()
        {
            var xDocument = new XDocument();
            var divXElement = new XElement("div");
            divXElement.Add(new XAttribute("id", "silverlightControlHost"));

            var objectXElement = new XElement("object");

            if (ID != null)
                objectXElement.Add(new XAttribute("id", ID));
            objectXElement.Add(new XAttribute("data", "data:application/x-silverlight-2,"));
            objectXElement.Add(new XAttribute("type", "application/x-silverlight-2"));
            objectXElement.Add(new XAttribute("width", Width.Value + GetUnitString(Width.Type)));
            objectXElement.Add(new XAttribute("height", Height.Value + GetUnitString(Height.Type)));
            objectXElement.Add(CreateParameter("source", Source.ToString()));

            if (AllowHtmlPopupWindow != null)
                objectXElement.Add(CreateParameter("allowHtmlPopupWindow", AllowHtmlPopupWindow.ToString()));
            if (AutoUpgrade != null)
                objectXElement.Add(CreateParameter("autoUpgrade", AutoUpgrade.ToString()));
            if (Enablehtmlaccess != null)
                objectXElement.Add(CreateParameter("enablehtmlaccess", Enablehtmlaccess.ToString()));
            if (EnableNavigation != null)
                objectXElement.Add(CreateParameter("enableNavigation", EnableNavigation.ToString()));
            if (Version != SilverlightVersion.Unknown)
                objectXElement.Add(CreateParameter("minRuntimeVersion",
                                                   SilverlightVersionHelper.GetMinimumVersion(Version)));
            if (OnError != null)
                objectXElement.Add(CreateParameter("onError", OnError));
            if (OnFullScreenChanged != null)
                objectXElement.Add(CreateParameter("onFullScreenChanged", OnFullScreenChanged));
            if (OnLoad != null)
                objectXElement.Add(CreateParameter("onLoad", OnLoad));
            if (OnResize != null)
                objectXElement.Add(CreateParameter("onResize", OnResize));
            if (OnSourceDownloadComplete != null)
                objectXElement.Add(CreateParameter("onSourceDownloadComplete", OnSourceDownloadComplete));
            if (OnSourceDownloadProgressChanged != null)
                objectXElement.Add(CreateParameter("onSourceDownloadProgressChanged", OnSourceDownloadProgressChanged));
            objectXElement.Add(CreateParameter("background", BackGround.Name.ToLower()));

            if (InitParams != null && InitParams.Count > 0)
            {
                var stringBuilder = new StringBuilder();
                foreach (var initParam in InitParams)
                {
                    if (stringBuilder.Length > 0)
                        stringBuilder.Append(",");
                    stringBuilder.Append(initParam.Key + "=" + initParam.Value);
                }
                objectXElement.Add(CreateParameter("initParams", stringBuilder.ToString()));
            }

            var installLinkXElemenet = new XElement("a");
            installLinkXElemenet.Add(new XAttribute("href", SilverlightVersionHelper.GetUpgradeUrl(Version)));
            installLinkXElemenet.Add(new XAttribute("style", "text-decoration:none"));

            var silverlightImageXElement = new XElement("img");
            silverlightImageXElement.Add(new XAttribute("src", "http://go.microsoft.com/fwlink/?LinkId=108181"));
            silverlightImageXElement.Add(new XAttribute("alt", "Get Microsoft Silverlight"));
            silverlightImageXElement.Add(new XAttribute("style", "border-style:none"));

            installLinkXElemenet.Add(silverlightImageXElement);
            objectXElement.Add(installLinkXElemenet);

            var iFrameXElement = new XElement("iframe", " ");
            iFrameXElement.Add(new XAttribute("id", "_sl_historyFrame"));
            iFrameXElement.Add(new XAttribute("style", "visibility:hidden;height:0px;width:0px;border:0px"));

            divXElement.Add(objectXElement);
            divXElement.Add(iFrameXElement);

            xDocument.Add(divXElement);

            return xDocument.ToString();
        }

        private static XElement CreateParameter(string Name, string Value)
        {
            var paramXElement = new XElement("param");
            paramXElement.Add(new XAttribute("name", Name));
            paramXElement.Add(new XAttribute("value", Value));
            return paramXElement;
        }

        private static string GetUnitString(UnitType UnitType)
        {
            string ret;
            switch (UnitType)
            {
                case UnitType.Pixel:
                    ret = "px";
                    break;
                case UnitType.Em:
                    ret = "em";
                    break;
                case UnitType.Ex:
                    ret = "ex";
                    break;
                case UnitType.Inch:
                    ret = "in";
                    break;
                case UnitType.Cm:
                    ret = "cm";
                    break;
                case UnitType.Mm:
                    ret = "mm";
                    break;
                case UnitType.Point:
                    ret = "pt";
                    break;
                case UnitType.Pica:
                    ret = "pc";
                    break;
                default:
                    throw new NotImplementedException("UnitType " + UnitType + " is not supported");
            }

            return ret;
        }
    }

    public static class SilverlightVersionHelper
    {
        public static string GetMinimumVersion(SilverlightVersion Version)
        {
            string minimumVersion;
            switch (Version)
            {
                case SilverlightVersion.V2:
                    minimumVersion = "2.0.31005";
                    break;
                case SilverlightVersion.V3:
                    minimumVersion = "3.0.40624";
                    break;
                default:
                    minimumVersion = "3.0.40624";
                    break;
            }
            return minimumVersion;
        }

        public static string GetUpgradeUrl(SilverlightVersion version)
        {
            string upgradeUrl;
            switch (version)
            {
                case SilverlightVersion.V2:
                    upgradeUrl = "http://go.microsoft.com/fwlink/?LinkID=149156&v=2.0.31005.0";
                    break;
                case SilverlightVersion.V3:
                    upgradeUrl = "http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0";
                    break;
                default:
                    upgradeUrl = "http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0";
                    break;
            }
            return upgradeUrl;
        }
    }

    public enum SilverlightVersion
    {
        Unknown,
        V2,
        V3
    }

    public class InitParam
    {
        public InitParam(string ParamName, string ParamValue)
        {
            Key = ParamName;
            Value = ParamValue;
        }

        public string Key { get; set; }
        public string Value { get; set; }
    }
}